package com.wh.base.config;

import java.util.HashMap;
import java.util.Map;

import org.eclipse.jetty.util.StringUtil;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.DataSourceConfig;
import com.baomidou.mybatisplus.generator.config.GlobalConfig;
import com.baomidou.mybatisplus.generator.config.PackageConfig;
import com.baomidou.mybatisplus.generator.config.StrategyConfig;
import com.baomidou.mybatisplus.generator.config.TemplateConfig;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;

/**
 * 代码生成器
 */
public class GenCode {

	public static void main(String[] args) {
		String tableNames = "sys_log";// 通过表名生成相关类,多个用英文逗号隔开
		String tablePrefix = "sys_";// 去掉表名前缀
		String packageName = "com.wh.base.sys.log";// 自定义自己的包名，后续的代码生成会在这个包下
		String moduleName = "sys";  //模块名
		String projectPath = "D:\\workspace\\workspace_springboot\\base\\src\\main\\java\\";// 生成文件的输出目录 
		String logModule = "日志"; //日志模块名称,用于生成日志注解
		//自定参数
		Map<String, String> customParam = new HashMap<>();
		customParam.put("moduleName", moduleName);
		customParam.put("logModule", logModule);
		
		new AutoGenerator()
		.setGlobalConfig(getGlobalConfig(projectPath))  //全局配置
		.setDataSource(getDataSource()) //数据源配置
		.setPackageInfo(getPackageConfig(packageName)) //包配置
		.setStrategy(getStrategyConfig(tableNames, tablePrefix))  //策略配置
		.setTemplate(getTemplateConfig())  //模板配置
		.setTemplateEngine(new FreemarkerTemplateEngine())  //设置模板引擎
		.setCfg(getInjectionConfig(customParam))  //设置自定义参数
		.execute();
	}

	/**
	 * 全局配置
	 *
	 * @param projectPath 生成文件的输出目录
	 */
	private static GlobalConfig getGlobalConfig(String projectPath) {
		//全局配置
		GlobalConfig gc = new GlobalConfig();
		gc.setOutputDir(projectPath)// 生成文件的输出目录
		.setAuthor("WangHong")// 作者
		.setOpen(false)// 是否打开输出目录 默认值:true
		.setFileOverride(true)// 是否覆蓋已有文件 默认值：false
		.setSwagger2(true)// 开启 swagger2 模式 默认false
		.setBaseColumnList(true)// 开启 baseColumnList 默认false
		.setBaseResultMap(true)// 开启 BaseResultMap 默认false
		.setIdType(IdType.AUTO)// 主键策略 ASSIGN_UUID:主键生成32位字符串ID
		.setDateType(DateType.ONLY_DATE)// 设置时间类型使用哪个包下的
		//.setEntityName("%sDO")// entity 命名方式 默认值：null 例如：%sEntity 生成 UserEntity
		.setMapperName("%sMapper")// dao 命名方式 默认值：null 例如：%sDao 生成 UserDao
		.setXmlName("%sMapper")// Mapper xml 命名方式   默认值：null 例如：%sDao 生成 UserDao.xml
		.setServiceName("%sService")// service 命名方式   默认值：null 例如：%sBusiness 生成 UserBusiness
		.setServiceImplName("%sServiceImpl")// service impl 命名方式  默认值：null 例如：%sBusinessImpl 生成 UserBusinessImpl
		.setControllerName("%sController")// controller 命名方式    默认值：null 例如：%sAction 生成 UserAction
		;
		return gc;
	}

	/**
	 * 数据源配置
	 */
	private static DataSourceConfig getDataSource() {
		DataSourceConfig dsc = new DataSourceConfig();
		dsc.setUrl(
				"jdbc:mysql://localhost:3306/base?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC"
				);
		dsc.setDriverName("com.mysql.cj.jdbc.Driver");
		dsc.setUsername("root");
		dsc.setPassword("123456");
		return dsc;
	}

	/**
	 * 包配置
	 *
	 * @param packageName 自定义包名，后续的代码生成会在这个包下
	 */
	private static PackageConfig getPackageConfig(String packageName) {
		PackageConfig pc = new PackageConfig();
		pc.setParent(packageName)
		.setController("controller")
		.setService("service")
		.setMapper("mapper")
		.setEntity("entity");
		return pc;
	}

	/**
	 * 策略配置
	 *
	 * @param tableNames 需要生成的表名
	 */
	private static StrategyConfig getStrategyConfig(String tableNames, String tablePrefix) {
		// 策略配置    数据库表配置，通过该配置，可指定需要生成哪些表或者排除哪些表
		StrategyConfig strategy = new StrategyConfig();
		strategy.setCapitalMode(true)//驼峰命名
		.setNaming(NamingStrategy.underline_to_camel)//表名生成策略(下划线转驼峰)
		.setColumnNaming(NamingStrategy.underline_to_camel)//列名生成策略(下划线转驼峰)
		.setEntityLombokModel(true)//【实体】是否为lombok模型（默认 false）
		.setRestControllerStyle(false)//生成 @RestController 控制器
		.setInclude((tableNames).split(","))//通过表名生成相关类
		.setTablePrefix(tablePrefix)//去掉表的前缀
		.setControllerMappingHyphenStyle(true);//驼峰转连字符
		//自定义继承的类全称，带包名
		/*strategy.setSuperControllerClass("com.common.BaseController");
    strategy.setSuperServiceClass((String) null);
    strategy.setSuperServiceImplClass((String) null);
    strategy.setSuperMapperClass(null);
    strategy.setSuperEntityClass("com.common.BaseEntity")
    strategy.setSuperEntityColumns("id");*/
		return strategy;
	}

	/**
	 * 模板配置：velocity模板
	 */
	private static TemplateConfig getTemplateConfig() {
		TemplateConfig tc = new TemplateConfig();
		//使用resource下的自定义模板，不想要生成就设置为null,如果不设置null会使用默认模板
		tc.setController("templates/genCode/controller_custom.java")
		.setService("templates/genCode/service.java")
		.setServiceImpl("templates/genCode/serviceImpl.java")
		.setEntity("templates/genCode/entity.java")
		.setMapper("templates/genCode/mapper_custom.java")
		.setXml("/templates/genCode/mapper.xml");
		return tc;
	}
	
	public static InjectionConfig getInjectionConfig (Map<String, String> customParam) {
		// 自定义配置
        InjectionConfig cfg = new InjectionConfig() {
        	//设置自定义参数
            @Override
            public void initMap() {
            	Map<String, Object> map = new HashMap<>();
            	if(customParam != null) {
            		map.putAll(customParam);
            	}
            	this.setMap(map);
            }
        };

        return cfg;

	}
}